/**
 * 关联代码库
 * okFn 关联成功，刷新父组件的列表
 * */
import React from 'react';
import PropTypes from 'prop-types';
import { Dialog, Search, Message, Checkbox, Button } from '@teamix/ui';
import exceed from 'utils/apimap';
import List from '@txdfe/at-list';
import ListLoading from 'atComponents/ListLoading';
import { defaultPageSize } from 'utils/constants.js';
import ListEmpty from 'atComponents/ListEmpty';
import TextAvatar from '@txdfe/at-text-avatar';
import debounce from 'lodash.debounce';
import './index.scss';
import utils from 'utils';
import intl from '../../locale';

const tbProjectId = utils.getUrlSearchParam('projectId');

export default class LinkProjectModal extends React.Component {
  static propTypes = {
    trigger: PropTypes.element,
    closeModal: PropTypes.func,
    okFn: PropTypes.func,
    // isModalOpen: PropTypes.bool,
  };

  static defaultProps = {
    trigger: null,
    closeModal: () => {},
    okFn: () => {},
    // isModalOpen: false,
  };

  constructor(props) {
    super(props);
    this.state = {
      submitting: false,
      isModalOpen: false,
      search: '',
      selectIds: [],
      projects: [],
      projectsLoaded: false,
    };

    this.optionsRef = React.createRef();
    this.filterData = debounce(this.getData, 500);
  }

  static getDerivedStateFromProps(props) {
    if (props.trigger) {
      return {};
    }
    return {
      isModalOpen: props.isModalOpen,
    };
  }

  componentDidMount() {
    this.getData(1);
  }

  searchData = (search) => {
    this.setState(
      {
        search,
      },
      () => {
        this.filterData(1);
      },
    );
  };

  // 通过页码获取数据
  getData = (page) => {
    exceed
      .fetch({
        api: 'tbProject.unLinkedList',
        params: {
          tbProjectId,
        },

        data: {
          page,
          search: this.state.search,
        },
      })
      .then((result) => {
        const data = result.slice(1) || [];
        const total = result[0].amount;

        const curProjects = page === 1 ? [...data] : [...this.state.projects, ...data];
        this.setState({
          projects: curProjects,
          total,
          currentPage: page,
          projectsLoaded: true,
        });
      })
      .fail((err) => {
        console.error(err);
      });
  };

  showModal = () => {
    this.setState({
      isModalOpen: true,
    });
  };

  onClose = () => {
    this.setState({
      isModalOpen: false,
    });

    this.props.closeModal();
  };

  handleOk = () => {
    const { submitting, selectIds } = this.state;
    if (submitting) {
      return;
    }
    this.setState({ submitting: true });
    this.formSubmit(selectIds);
  };

  formSubmit = (selectIds) => {
    const selectPromise = new Promise((resolve, reject) => {
      exceed
        .fetch({
          api: 'tbProject.link',
          params: {
            tbProjectId,
          },

          data: {
            project_ids: selectIds.join(','),
          },
        })
        .then((result) => {
          resolve(result);
        })
        .fail((err) => {
          reject(err);
        });
    });
    selectPromise
      .then(() => {
        Message.success({
          title: intl.get({
            id: 'code-assets.components.linkProjectModal.TheCodeLibraryIsAssociated',
            defaultMessage: '代码库关联成功',
          }),
        });

        this.setState({
          submitting: false,
        });

        this.onClose();
        this.props.okFn();
      })
      .catch(() => {
        Message.error({
          title: intl.get({
            id: 'code-assets.components.linkProjectModal.CodeBaseAssociationFailure',
            defaultMessage: '代码库关联失败',
          }),
        });

        this.setState({
          submitting: false,
        });
      });
  };

  selectProject = (value, projectId) => {
    const curSelectIds = [...this.state.selectIds];
    if (value) {
      if (!curSelectIds.includes(projectId)) {
        curSelectIds.push(projectId);
      }
    } else {
      const index = curSelectIds.indexOf(projectId);
      if (index > -1) {
        curSelectIds.splice(index, 1);
      }
    }
    this.setState({
      selectIds: curSelectIds,
    });
  };

  renderOptions = () => {
    const { currentPage, total, projects, projectsLoaded, search } = this.state;
    const hasMore = currentPage * defaultPageSize < total;
    if (!projectsLoaded) {
      return (
        <div style={{ marginTop: '100px' }}>
          <ListLoading />
        </div>
      );
    }
    if (!projects.length) {
      if (search) {
        return (
          <ListEmpty
            description={
              <div className="link-modal-des">
                {intl.get({
                  id: 'code-assets.components.linkProjectModal.NoSearchResultsAreFound',
                  defaultMessage: '暂无搜索结果',
                })}
              </div>
            }
            imgType="search"
          />
        );
      }
      return (
        <ListEmpty
          content={
            <div className="link-modal-des">
              {intl.get({
                id: 'code-assets.components.linkProjectModal.NoAssociatedCodeLibrariesAre',
                defaultMessage: '没有可关联的代码库',
              })}
            </div>
          }
          image="none"
        />
      );
    }
    return (
      <List
        pagination={{
          onLoadMore: (page) => {
            this.getData(page);
          },
          hasMore,
          useWindow: false,
          getScrollParent: () => {
            return this.optionsRef.current;
          },
        }}
      >
        {projects.map((project) => {
          const checked = this.state.selectIds.includes(project.id);
          return (
            <div key={project.id} className="link-project-option">
              <Checkbox
                checked={checked}
                onChange={(value) => {
                  this.selectProject(value, project.id);
                }}
              >
                <span className="line-project-avatar">
                  <TextAvatar
                    text={project.path.toUpperCase()}
                    image={project.avatar_url}
                    href={`/${project.path_with_namespace}`}
                    isCover
                    size="xs"
                  />
                </span>
                <span className="option-project-name one-line-ellipsis">{project.name}</span>
              </Checkbox>
            </div>
          );
        })}
      </List>
    );
  };

  render() {
    const { selectIds, submitting } = this.state;
    return (
      <React.Fragment>
        {this.state.isModalOpen ? (
          <Dialog
            title={intl.get({
              id: 'code-assets.components.linkProjectModal.AssociateExistingDatabases',
              defaultMessage: '关联已有库',
            })}
            visible
            style={{ width: '440px' }}
            onClose={this.onClose}
            footer={
              <div className="link-project-footer">
                <div className="link-project-footer-left">
                  {selectIds.length
                    ? intl.get(
                        {
                          id: 'code-assets.components.linkProjectModal.SelectidslengthObjectsSelected',
                          defaultMessage: '已选择{selectIdsLength}个对象',
                        },
                        { selectIdsLength: selectIds.length },
                      )
                    : ''}
                </div>
                <div className="link-project-footer-right">
                  <Button type="normal" onClick={this.onClose}>
                    {intl.get({
                      id: 'code-assets.components.linkProjectModal.Cancel',
                      defaultMessage: '取消',
                    })}
                  </Button>
                  <Button
                    type="primary"
                    onClick={this.handleOk}
                    disabled={selectIds.length === 0}
                    loading={submitting}
                    style={{ marginLeft: 12 }}
                  >
                    {intl.get({
                      id: 'code-assets.components.linkProjectModal.Determine',
                      defaultMessage: '确定',
                    })}
                  </Button>
                </div>
              </div>
            }
          >
            <div className="link-project-content">
              <div className="link-project-search">
                <Search
                  placeholder={intl.get({
                    id: 'code-assets.components.linkProjectModal.SearchCodeBase',
                    defaultMessage: '搜索代码库',
                  })}
                  style={{ width: '100%' }}
                  onChange={this.searchData}
                />
              </div>
              <div className="link-project-options" ref={this.optionsRef}>
                {this.renderOptions()}
              </div>
            </div>
          </Dialog>
        ) : null}
        {!!this.props.trigger &&
          React.cloneElement(this.props.trigger, {
            onClick: () => {
              this.showModal();
            },
          })}
      </React.Fragment>
    );
  }
}
